# -*- coding: utf-8 -*-
__author__ = 'lztkdr'
__date__ = '2020/4/10 8:33'

"""
 pandas 性能 提升的方式
 
"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# Pycharm输出窗口有省略号，数据显示不全解决方法
pd.set_option('display.max_rows', 10)
pd.set_option('display.max_columns', 200)
pd.set_option('display.width', 1000)

# 如果要显示中文标题和坐标表示，需要添加以下两行代码
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

print('pd.__version__:', pd.__version__)

print('============================================================================================================')

def mytimeit(repeat):
	"""
	执行耗时计时
	:param repeat: 执行次数
	:return:
	"""
	import time
	def wrapper(fun):
		def inner(*args, **kwargs):
			total = 0
			for j in range(0, repeat):
				start = time.perf_counter()
				fun(*args, **kwargs)
				end = time.perf_counter()
				total += (end - start)
			print(fun.__name__, '执行', repeat, '次，总执行耗时：', str(round(total, 2)) + 's', '平均耗时：',
			      str(round(total / repeat, 2)) + 's')

		return inner

	return wrapper


print('============================================================================================================')

"""
date_time 每小时
energy_kwh 每小时 使用电 能量千瓦时
"""
# pd.date_range 生成时间，freq：M 月 D 天 H 小时
df = pd.DataFrame(data={
	'date_time': pd.date_range(start='1/1/13 00:00', end='12/31/13 23:00', freq='H').astype(str),
	'energy_kwh': np.round(np.random.uniform(0.5, 0.62, 8760), 3)
})
print('dtypes:', df.dtypes)
print(df)
print('==============================================')


from timer import timeit

# 执行 3*1000 次
# 3个试验中的最好的，每个试验有1000个函数调用
@timeit(repeat=3, number=1000)
def convert(df, column_name):
	return pd.to_datetime(df[column_name])


if __name__ == '__main__':
	df.date_time = convert(df, 'date_time')
	print(df.dtypes)
	"""
	中文链接：
		https://mp.weixin.qq.com/s?__biz=MzIxNjM4NDE2MA==&mid=2247490397&idx=2&sn=303a9e833abe83a8a5a6a4ed7a927d0e&chksm=97888c92a0ff05842522a50fcca6872b1c217ae39766a67eeaa13592fb59d7b3dea96a6d2aa0&mpshare=1&scene=23&srcid=0410Zp0JeLa2xH2VFqLOvjr0&sharer_sharetime=1586473986711&sharer_shareid=d267f26442147f9849f60be756ca88c5#rd
	英文链接：
		https://realpython.com/fast-flexible-pandas/
		
	用Datetime类节省时间 
	遍历
	用.itertuples()和.iterrow()遍历     for index, row in df.iterrows():
	Pandas的.apply()
	用.isin()筛选数据
	使用Pandas的pd.cut()功能
	还有NumPy！ NumPy的digitize()功能
	用HDFstore存储预处理数据

	====================================================================================================================
	1. 使用向量化操作：没有for遍历的Pandas方法和函数。
	
	2. 使用.apply()方法。
	
	3. 使用.itertuples()：将DataFrame行作为nametuple类从Python的collections模块中进行迭代。
	
	4. 使用.iterrows()：将DataFrame行作为（index，pd.Series）元组数组进行迭代。虽然Pandas的Series是一种灵活的数据结构，但将每一行生成一个Series并且访问它，仍然是一个比较大的开销。
	
	5. 对逐个元素进行循环，使用df.loc或者df.iloc对每个单元格或者行进行处理。
	====================================================================================================================
	如果觉得你的Pandas项目不具备速度快、灵活、简单且直观的特征，那么该重新思考使用该库的方式了。 

	① 尝试更多的向量化操作，尽量避免类似for x in df的操作。如果代码中本身就有许多for循环，那么尽量使用Python自带的数据结构，因为Pandas会带来很多开销。
	
	② 如果因为算法复杂无法使用向量化操作，可以尝试.apply()方法。
	
	③ 如果必须循环遍历数组，可用.iterrows()或者.itertuples()改进语法和提升速度。
	
	④ Pandas有很多可选项操作，总有几种方法可以完成从A到B的过程，比较不同方法的执行方式，选择最适合项目的一种。
	
	⑤ 做好数据处理脚本后，可以将中间输出的预处理数据保存在HDFStore中，避免重新处理数据。
	
	⑥ 在Pandas项目中，利用NumPy可以提高速度同时简化语法。
	

	"""


